<?php

namespace app\middleware;

use ReflectionClass;
use support\Redis;
use Tinywan\Jwt\JwtToken;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class TokenAuthMiddleware implements MiddlewareInterface
{
    // 定义白名单路由
    private $whitelist = [
        '/api/customer/register',
        '/api/customer/login',
        "/api/index/handleError",
    ];

    public function process(Request $request, callable $next): Response
    {

        $controller  = new ReflectionClass($request->controller);
        $noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];

        if (in_array($request->action, $noNeedLogin)) {
            // 判断是否在不需要登录名单
            return $next($request);
        }

        // 获取当前请求的路径
        $path = $request->path();

        // 检查请求路径是否在白名单中
        if (in_array($path, $this->whitelist)) {
            // 若在白名单中，直接继续处理请求
            return $next($request);
        }

        // 从请求头中获取 Token
        $token = $request->header('Authorization');
        if (! $token) {
            // 若未携带 Token，返回错误响应
            return json(['code' => 401, 'message' => '未提供 Token']);
        }

        // 去除 Token 前缀（如 "Bearer "）
        $token = str_replace('Bearer ', '', $token);

        try {
            // 验证 Token
            $uid = JwtToken::getCurrentId();
            // 将用户信息存入请求对象，方便后续使用
            $request->uid = $uid;
            // 验证redis中是否存在token
            $redisToken = Redis::get("token:" . $uid);
            if ($token != $redisToken) {
                return json(['code' => 401, 'message' => '无效的Token']);
            }
        } catch (\Exception $e) {
            // 若 Token 验证失败，返回错误响应
            return json(['code' => 401, 'message' => '无效的 Token: ' . $e->getMessage()]);
        }

        // Token 验证通过，继续处理请求
        return $next($request);
    }
}
